﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using SRAGWMCLib.OO;
using SRAGWMCLib;
using System.Drawing;
using System.Data.OleDb;

namespace SRAGWMap
{
    //metodo criar checkboxes
    //metodo para construir legendentries
    //propriedade show = visible
    /// <summary>
    /// Utilizes the .DLL to display a map and various features
    /// </summary>
    ///     
    public partial class SRAGWMap : System.Web.UI.Page
    {
        # region ---------------- Public Variables ----------------

        public String AuxMap { get; set; }

        string MSS;
        object[] Pnts = new object[6];
        static object[] InitialRange = new object[4]{0.0,0.0,0.0,0.0};
        object[] Rng = new object[4] { 0.0, 0.0, 0.0, 0.0 };
        static double dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0, MagFact = 0;
        ArrayList obj = new ArrayList();
        //TODO Apagar objecto
        LegendEntryCollection LegendEntries;
        DataBaseCollection DataBaseEntries = new DataBaseCollection();

        #endregion
        #region ---------------- Initialize ----------------
        public Control GetPostBackControl()
        {
            Control control = null;

            string ctrlname = Page.Request.Params.Get("__EVENTTARGET");
            if (ctrlname != null && ctrlname != string.Empty)
            {
                control = Page.FindControl(ctrlname);
            }
            else
            {
                foreach (string ctl in Page.Request.Form)
                {
                    Control c = Page.FindControl(ctl);
                    if (c is System.Web.UI.WebControls.Button)
                    {
                        control = c;
                        break;
                    }
                }
            }
            return control;
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
                MapDisplay();
        }

        private bool HasFeatureSelected()
        {
            bool retVal = false;
            foreach (var le in LegendEntries)
                if (!le.Visible == true)
                    retVal = true;
            return retVal;
        }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            BuildLegend();
        }
        //parametros iniciais
        private static void InitializeParameters()
        {
            dx1 = 0; dy1 = 0; dx2 = 0; dy2 = 0; MagFact = 1;
        }

        private void BuildLegend()
        {
            //CARREGA AS FEATURES
            LegendEntries = FeatureLoader.Load(Pnts);

            foreach (LegendEntry le in LegendEntries)
            {
                CheckBox checkBox = new CheckBox();
                checkBox.Text = le.DataSource.DBMarkerName;
                checkBox.ID = checkBox.Text;
                checkBox.AutoPostBack = true;
                checkBox.Checked = le.Visible;
                checkBox.CheckedChanged += new EventHandler(OnCheckedChange);
                Panel_Checkboxes.Controls.Add(checkBox);
                Panel_Checkboxes.Controls.Add(new LiteralControl("<br />"));//trata br entre as checkbox e as dropdownlist
                //Adicionar a combobox com os campos
                DropDownList dropDownFeatureFieldsList = new DropDownList();
                dropDownFeatureFieldsList.ID = "Field_" + le.DataSource.DBMarkerName;
                dropDownFeatureFieldsList.AutoPostBack = true;
                dropDownFeatureFieldsList.SelectedIndexChanged += new EventHandler(dropDownFeatureFieldsList_SelectedIndexChanged);

                //Iterate throuth the database
                foreach (string field in le.DataSource.TableFields)
                {
                    ListItem lst = new ListItem();
                    lst.Text = lst.Value = field;
                    //seleccionda primeiro campo da lista
                    dropDownFeatureFieldsList.Items.Add(lst);
                }
                dropDownFeatureFieldsList.Items[0].Selected = true;
                Panel_Checkboxes.Controls.Add(dropDownFeatureFieldsList);
                //trata distanciamento de uma linha entre as dropdownlist
                Panel_Checkboxes.Controls.Add(new LiteralControl("<br />"));
                Panel_Checkboxes.Controls.Add(new LiteralControl("<br />"));
            }
        }
        /// <summary>
        /// Evento Change das checkboxes das features
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        protected void OnCheckedChange(object sender, EventArgs args)
        {
            base.OnInit(args);
            MapDisplay();
        }
        /// <summary>
        /// Evento de Mudança de index da combobox dos campos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void dropDownFeatureFieldsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            base.OnInit(e);
            ChangeFeatureTooltip();
            MapDisplay();
        }

        private void ChangeFeatureTooltip()
        {
            DropDownList dropDown = (DropDownList)GetPostBackControl();
            foreach (LegendEntry le in LegendEntries)
                if ("Field_" + le.DataSource.DBMarkerName == dropDown.ID)
                {
                    le.Tooltip = "<%." + dropDown.SelectedItem.Text + "%" + ">";
                    le.DataSource.TableFields = new string[] { dropDown.SelectedItem.Text };
                }

        }

        void SetMapPolygon()
        {
            Pnts[0] = -315432.33;
            Pnts[1] = 8909.76;
            Pnts[2] = 104033.34;
            Pnts[3] = -837648.24;
            Pnts[4] = 485365.78;
            Pnts[5] = -219889.71;
        }
        #endregion
        void MapFeatures()
        {
            GetRangeToFitFeatures();
            InitialRange = Rng;
        }
        /// <summary>
        /// Get the range that will enable the fit of all the legend entries selected
        /// </summary>
        private void GetRangeToFitFeatures()
        {
            bool first = true;

            foreach (LegendEntry le in LegendEntries)
            {
                if (!((CheckBox)Panel_Checkboxes.FindControl(le.DataSource.DBMarkerName)).Checked) continue;
                le.Visible = true;
                object[] auxRng = (object[])GWMHelper.DisplayFeature(le);
                if (first)
                {
                    first = false;
                    Rng = auxRng;
                }
                else
                {
                    if ((double)auxRng[0] < (double)Rng[0]) Rng[0] = auxRng[0];
                    if ((double)auxRng[1] < (double)Rng[1]) Rng[1] = auxRng[1];
                    if ((double)auxRng[2] > (double)Rng[2]) Rng[2] = auxRng[2];
                    if ((double)auxRng[3] > (double)Rng[3]) Rng[3] = auxRng[3];
                }

            }
        }

        //MapDisplay ----------------

        void ZoomFactor()
        {
            #region ---------------- Map Zoom value ----------------
            MSS = Request.QueryString["mss"];
            if (MagFact == 0)
            {
                MagFact = 1;
            }
            else
            {
                double MagFacTotal;
                if (Request.QueryString["MagFacMultiplier"] != null)
                {
                    MagFact = double.Parse(Request.QueryString["MagFacMultiplier"]);
                    MagFacTotal = MagFact - 1;
                }
            }
            #endregion
        }

        void MapDisplay()
        {

            if (HasFeatureSelected())
            {
                Color BackgroundColor = Color.White;
                SRAMapServer SRAMapServer = new SRAMapServer(
                    (int)OutputType.ActiveCGM32bit,//Tipo de ficheiro do mapa
                    BackgroundColor//cor de fundo do mapa
                    );
                GWMHelper.SetMapSettings(SRAMapServer);
                DataBaseEntries = ConnectionLoader.Load("");

                //Define DataBase and Coordinate System ----------------
                foreach (DataBase db in DataBaseEntries)
                    GWMHelper.Connect(db);

                //Map Zoom and Features ----------------
                ZoomFactor();
                MapFeatures();
            }
            //Display Map ----------------
            Range Range = new Range(MagFact, 400000000, 10000);
            if (!Page.IsPostBack)
            {
                MapAttributes.Range = Rng;
                MapAttributes.Width = 700;
                MapAttributes.Height = 450;
            }
            GWMHelper.GenerateMap(Range);
            MAPSRVLib.GWMMapServerHelper MapServer = (MAPSRVLib.GWMMapServerHelper)SRAMapServerBuilder.GetMap();
            
            AuxMap = MapServer.OutputFile;//Propriedade que faz o display do mapa da pagina aspx
        }

        #region ---------------- Pan And Zoom Event Handlers ----------------
        //metodo deslocacao vertical
        private static void ChangeVerticalRange(double dy1, double dy2)
        {
            double dy = Convert.ToDouble(MapAttributes.Range[3]) - Convert.ToDouble(MapAttributes.Range[1]);
            MapAttributes.Range[1] = Convert.ToDouble(MapAttributes.Range[1]) + dy * dy1;
            MapAttributes.Range[3] = Convert.ToDouble(MapAttributes.Range[3]) + dy * dy2;
        }
        //metodo deslocacao horizontal
        private static void ChangeHorizontalRange(double dx1, double dx2)
        {
            double dx = Convert.ToDouble(MapAttributes.Range[2]) - Convert.ToDouble(MapAttributes.Range[0]);
            MapAttributes.Range[0] = Convert.ToDouble(MapAttributes.Range[0]) + dx * dx1;
            MapAttributes.Range[2] = Convert.ToDouble(MapAttributes.Range[2]) + dx * dx2;
        }
        //centra
        protected void imgbtn_fit_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
                MapAttributes.Range = Rng = InitialRange;
                InitializeParameters();
                MapDisplay();
            }
            catch (Exception i)
            {
                string ex = i.ToString();
            }
        }
        //mais zoom
        protected void imgbtn_plus_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
            MagFact -= 0.1;
            MapDisplay();
                }
            catch (Exception i)
            {
                string ex = i.ToString();
            }
        }
        //menos zoom
        protected void imgbtn_less_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
            MagFact += 0.1;
            MapDisplay();
            }
            catch (Exception i)
            {
                string ex = i.ToString();
            }
            }
        //cima
        protected void imgup_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
            dy1 = dy2 = 0.05;
            ChangeVerticalRange(dy1, dy2);
            MapDisplay();
            }
            catch (Exception i)
            {
                string ex = i.ToString();
            }
            }
        //baixo
        protected void imgdown_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
            dy1 = dy2 = -0.05;
            ChangeVerticalRange(dy1, dy2);
            MapDisplay();
            }
            catch (Exception i)
            {
                string ex = i.ToString();
            }
        }
        //esquerda
        protected void imgleft_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
            dx1 = dx2 = -0.05;
            ChangeHorizontalRange(dx1, dx2);
            MapDisplay();
        }    
            catch (Exception i)
            {
                string ex = i.ToString();
            }
        }
        //direita
        protected void imgright_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
            dx1 = dx2 = 0.05;
            ChangeHorizontalRange(dx1, dx2);
            MapDisplay();
            }
            catch (Exception i)
            {
                string ex = i.ToString();
            }
        }
        //noroeste
        protected void imgnorthwest_Click(object sender, ImageClickEventArgs e)
        {
         try
         {
            dx1 = dx2 = -0.05;
            dy1 = dy2 = 0.05;
            ChangeHorizontalRange(dx1, dx2);
            ChangeVerticalRange(dy1, dy2);
            MapDisplay();
        }
         catch (Exception i)
         {
             string ex = i.ToString();
         }
        }
        //sudeste
        protected void imgsoutheast_Click(object sender, ImageClickEventArgs e)
        {
         try
         {
             dx1 = dx2 = 0.05;
            dy1 = dy2 = -0.05;
            ChangeHorizontalRange(dx1, dx2);
            ChangeVerticalRange(dy1, dy2);
            MapDisplay();
        }
         catch (Exception i)
         {
             string ex = i.ToString();
         }
        }
        //nordeste
        protected void imgnortheast_Click(object sender, ImageClickEventArgs e)
        {
         try
         {
             dx1 = dx2 = 0.05;
            dy1 = dy2 = 0.05;
            ChangeHorizontalRange(dx1, dx2);
            ChangeVerticalRange(dy1, dy2);
            MapDisplay();
         }
         catch (Exception i)
         {
             string ex = i.ToString();
         }
        }
        //sudoeste
        protected void imgsouthwest_Click(object sender, ImageClickEventArgs e)
        {
         try
         {
             dx1 = dx2 = -0.05;
            dy1 = dy2 = -0.05;
            ChangeHorizontalRange(dx1, dx2);
            ChangeVerticalRange(dy1, dy2);
            MapDisplay();
         }
         catch (Exception i)
         {
             string ex = i.ToString();
         }
        }
        #endregion
    }
}